package com.weimob.mcloud.wechatwork.customer.export;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.weimob.mcloud.wechatwork.customer.export.sentinel.SentinelCommonBlockHandler;
import com.weimob.mcloud.wechatwork.customer.facade.impl.CommonValid;
import com.weimob.mcloud.wechatwork.customer.mq.model.ChatGroupFacade;
import com.weimob.mcloud.wechatwork.customer.service.GroupService;
import com.weimob.mcloud.wechatwork.customer.service.user.base.PageResponse;
import com.weimob.mcloud.wechatwork.customer.service.user.exception.BizException;
import com.weimob.mcloud.wechatwork.customer.service.user.module.bo.group.*;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.group.*;
import com.weimob.mcloud.wechatwork.customer.service.user.module.model.group.SimpleGroupModel;
import com.weimob.mcloud.wechatwork.customer.service.user.service.group.ChatGroupExport;
import com.weimob.mcloud.wechatwork.customer.service.user.utils.SoaResponseUtil;
import com.weimob.soa.common.response.SoaResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author liuzhu.chen
 * @desc 客户群RPC接口
 * @date 2021/10/25
 */
@Service
@Slf4j
public class ChatGroupExportImpl implements ChatGroupExport {

    @Autowired
    GroupService groupService;

    @Autowired
    private ChatGroupFacade chatGroupFacade;

    @Autowired
    @Qualifier("customerGroupUpdateThreadPool")
    private ThreadPoolTaskExecutor customerGroupUpdateThreadPool;

    @Autowired
    private CommonValid commonValid;

    @Value("${group.query.max.page.size:100}")
    private Integer maxPageSize;


    @Override
    public SoaResponse<Boolean, ?> export(@Valid CorpChatGroupQueryDTO dto) {
        return SoaResponseUtil.ok(groupService.export(dto));
    }

    @Override
    public SoaResponse<CorpChatGroupDetailBO, ?> detail(@Valid CorpChatGroupDetailDTO dto) {
        return SoaResponseUtil.ok(groupService.queryDetail(dto));
    }

    @Override
    public SoaResponse<SimpleGroupModel, ?> fetchGroupWithRichMember(SimpleGroupQueryDTO simpleGroupQueryDTO) {
        return SoaResponseUtil.ok(groupService.fetchGroupWithRichMember(simpleGroupQueryDTO));
    }


    @Override
    public SoaResponse<RetailStoreExcelBO, ?> importExcel(RetailStoreExcelImportDTO dto) {
        return SoaResponseUtil.ok(groupService.importExcel(dto));
    }

    @Override
    public SoaResponse<PageResponse<CorpChatGroupListBO>, ?> listGroupJoinStore(@Valid CorpChatGroupQueryDTO dto) {
        PageResponse<CorpChatGroupListBO> corpChatGroupListBOPagination = groupService.listGroupJoinStore(dto);
        return SoaResponseUtil.ok(corpChatGroupListBOPagination);
    }

    @Override
    @SentinelResource(value = "customerGroupListForOpen", blockHandlerClass = SentinelCommonBlockHandler.class, blockHandler = "customerGroupListForOpenBlockHandler")
    public SoaResponse<PageResponse<CorpChatGroupListOpenBO>, ?> customerGroupListForOpen(@Valid CorpChatGroupQueryOpenDTO openDto) {
        // 校验ES分页最大深度
        commonValid.checkESWindowSize(openDto.getPageNum(), openDto.getPageSize());
        // 每页条数不可超过100条
        if (openDto.getPageSize() > maxPageSize) {
            throw new BizException("每页条数不可超过" + maxPageSize + "条");
        }
        CorpChatGroupQueryDTO groupQueryDto = new CorpChatGroupQueryDTO();
        groupQueryDto.setWid(openDto.getBid());
        groupQueryDto.setOwnerIdList(openDto.getOwnerIdList());
        groupQueryDto.setName(openDto.getName());
        groupQueryDto.setState(openDto.getState());
        groupQueryDto.setAuthorizationStatus(0);
        if(Objects.nonNull(openDto.getCreateTimeStart())){
            groupQueryDto.setCreateTimeStart(new Date(openDto.getCreateTimeStart()));
        }
        if(Objects.nonNull(openDto.getCreateTimeEnd())){
            groupQueryDto.setCreateTimeEnd(new Date(openDto.getCreateTimeEnd()));
        }
        groupQueryDto.setPageNum(openDto.getPageNum());
        groupQueryDto.setPageSize(openDto.getPageSize());
        groupQueryDto.setBasicInfo(openDto.convertToBasicInfo());

        PageResponse<CorpChatGroupListBO> corpChatGroupListBOPagination = groupService.listGroupJoinStore(groupQueryDto);

        List<CorpChatGroupListBO> results = corpChatGroupListBOPagination.getResults();
        List<CorpChatGroupListOpenBO> resultList  = new ArrayList<>();
        for (CorpChatGroupListBO result : results) {
            CorpChatGroupListOpenBO openBO = new CorpChatGroupListOpenBO();
            openBO.setName(result.getName());
            openBO.setOwner(result.getOwner());
            if(Objects.nonNull(result.getGroupCreateTime())){
                openBO.setGroupCreateTime(result.getGroupCreateTime().getTime());
            }
            openBO.setNum(result.getNum());
            openBO.setCustomerNum(result.getCustomerNum());
            openBO.setJoinNum(result.getJoinNum());
            openBO.setQuitNum(result.getQuitNum());
            openBO.setChatId(result.getChatId());
            openBO.setState(result.getState());
            BeanUtils.copyProperties(result,openBO);
            resultList.add(openBO);
        }
        PageResponse<CorpChatGroupListOpenBO> pagination = new PageResponse<>();
        pagination.setResults(resultList);
        pagination.setPageNum(corpChatGroupListBOPagination.getPageNum());
        pagination.setPageSize(corpChatGroupListBOPagination.getPageSize());
        pagination.setTotalPage(corpChatGroupListBOPagination.getTotalPage());
        pagination.setTotalCount(corpChatGroupListBOPagination.getTotalCount());
        return SoaResponseUtil.ok(pagination);
    }

    @Override
    public SoaResponse<List<GroupStatisticListBO>, ?> batchFetchGroupStatisticInfo(GroupStatisticQueryDTO dto) {
        List<GroupStatisticListBO> groupStatisticListBOList = groupService.batchFetchGroupStatisticInfo(dto);
        return SoaResponseUtil.ok(groupStatisticListBOList);
    }

    @Override
    public SoaResponse<PageResponse<CorpChatGroupMemberBO>, ?> memberList(@Valid CustomerGroupMemberQueryDTO dto){
        PageResponse<CorpChatGroupMemberBO> pageResponse = groupService.memberList(dto);
        return SoaResponseUtil.ok(pageResponse);
    }

    @Override
    @SentinelResource(value = "memberListForOpen", blockHandlerClass = SentinelCommonBlockHandler.class, blockHandler = "memberListForOpenBlockHandler")
    public SoaResponse<PageResponse<CorpChatGroupMemberOpenBO>, ?> memberListForOpen(@Valid CustomerGroupMemberQueryOpenDTO dto){
        CustomerGroupMemberQueryDTO memberQueryDTO = new CustomerGroupMemberQueryDTO();
        memberQueryDTO.setWid(dto.getBid());
        memberQueryDTO.setChatId(dto.getChatId());
        memberQueryDTO.setPageNum(dto.getPageNum());
        memberQueryDTO.setPageSize(dto.getPageSize());
        memberQueryDTO.setBasicInfo(dto.convertToBasicInfo());

        PageResponse<CorpChatGroupMemberBO> pageResponse = groupService.memberList(memberQueryDTO);

        List<CorpChatGroupMemberOpenBO> memberOpenBOList = new ArrayList<>();
        List<CorpChatGroupMemberBO> results = pageResponse.getResults();
        if(!CollectionUtils.isEmpty(results)){
            for (CorpChatGroupMemberBO memberBO : results) {
                CorpChatGroupMemberOpenBO memberOpenBO = new CorpChatGroupMemberOpenBO();
                memberOpenBO.setName(memberBO.getName());
                memberOpenBO.setType(memberBO.getType());
                if(Objects.nonNull(memberBO.getJoinTime())){
                    memberOpenBO.setJoinGroupTime(memberBO.getJoinTime().getTime());
                }
                memberOpenBO.setJoinScene(memberBO.getJoinScene());
                memberOpenBO.setInviteName(memberBO.getInviteName());
                memberOpenBOList.add(memberOpenBO);
            }
        }

        PageResponse<CorpChatGroupMemberOpenBO> pagination = new PageResponse<>();
        pagination.setResults(memberOpenBOList);
        pagination.setPageNum(pageResponse.getPageNum());
        pagination.setPageSize(pageResponse.getPageSize());
        pagination.setTotalPage(pageResponse.getTotalPage());
        pagination.setTotalCount(pageResponse.getTotalCount());

        return SoaResponseUtil.ok(pagination);
    }

    @Override
    public SoaResponse<Boolean, ?> memberExport(@Valid CustomerGroupMemberQueryDTO dto){
        return SoaResponseUtil.ok(groupService.memberExport(dto));
    }

    @Override
    public SoaResponse<RetailStoreModifyBO, ?> batchModifyStore(@Valid RetailStoreModifyDTO dto) {
        return SoaResponseUtil.ok(groupService.batchModifyStore(dto));
    }

    @Override
    public SoaResponse<RetailStoreModifyBO, ?> batchRelieveStore(@Valid RetailStoreModifyDTO dto) {
        return SoaResponseUtil.ok(groupService.batchRelieveStore(dto));
    }

    @Override
    public SoaResponse<PageResponse<CustomerChatGroupBO>, ?> getGroupChatListByMember(CustomerChatGroupDTO customerChatGroupDTO) {
        return SoaResponseUtil.ok(groupService.getGroupChatListByMember(customerChatGroupDTO));
    }

    @Override
    public SoaResponse<Boolean, ?> initChatGroup(String corpId) {
        customerGroupUpdateThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                chatGroupFacade.initChatGroupData(corpId, null);
            }
        });
        return SoaResponseUtil.ok(Boolean.TRUE);
    }


    @Override
    @SentinelResource(value = "getGroupChatListByWid", blockHandlerClass = SentinelCommonBlockHandler.class, blockHandler = "getGroupChatListByWidBlockHandler")
    public SoaResponse<PageResponse<CorpChatGroupListBO>, ?> getGroupChatListByWid(CustomerChatGroupDTO customerChatGroupDTO) {
        return SoaResponseUtil.ok(groupService.getGroupChatListByWid(customerChatGroupDTO));
    }
}
